home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
The Best of MacTutor - S…e Code for Volumes 1 to 5
/
The Best of MacTutor - Source Code for Volume 1-5 (Wayzata Technology)(6031)(1990).bin
/
Source Code
/
#49 (Oct 89)
/
SC #49.sit
/
Driver Code
/
DRVRStruct.a
next >
Wrap
Text File
|
1988-01-06
|
9KB
|
323 lines
TITLE 'DRVRStart - Parse a driver declaration'
MACRO
&Scope DRVRStart &ArgList,&Link
PRINT Push,NoMDir,NoMCall
.*
GBLC &ModName# ; <modname>
GBLC &FInfo# ; function <result>
GBLC &Args#[50] ; argument list
GBLA &NbrOfArgs# ; number of args in argument list
GBLC &StFrame# ; name of current stack frame
GBLC &DbgName# ; name to generate for MacsBug
GBLC &FSz# ; function result size
GBLA &Link# ; 1 ==> generate LINK
GBLA &HaveDcls# ; 1 ==> have local variables
GBLA &C# ; 1 ==> C function
.*
LCLA &Func,&Arg
LCLC &LinkOpt
.*
.* LinkAll is a user setable global controlling LINK generation
.*
IF &Type('LinkAll') = 'UNDEFINED' THEN ; Initialize LinkAll if required
PRINT Push,Off
LinkAll: SET 0
PRINT Pop
ENDIF
.*
.* Debug is a user setable global controlling MacsBug symbol generation
.*
IF &Type('Debug') = 'UNDEFINED' THEN ; Initialize Debug if required
PRINT Push,Off
Debug: SET 0
PRINT Pop
ENDIF
.*
.* Break up &ArgList into its components
.*
ScanArgs# &ArgList ; Set &ModName#, &Args#, &FInfo#
&Func: SETA 0 ;&Len(&FInfo#) ; &Func ≠ 0 if function
&C#: SETA 0 ;&UC(&C)='C' ; Remember if we have a C function
.*
.*
.* Generate module header and its corresponding scope
.*
&ModName# MAIN &Scope
.*
.* Start the proc's local stack frame
.*
&StFrame#: SETC &Concat('SF#', &SysNdx)
.*
&StFrame# RECORD {FramePtr},Decr
.*
&FSz#: SETC ''
.*
.* The return address always follows the formal list
.*
RetAddr DS.L 1
.*
.* Process the &Link parameter: indicates if LINK must be generated and whether
.* MacsBug symbol will be generated.
.*
&Link#: SETA 0 ; Assume LINK will not be needed
&LinkOpt: SETC &UC(&Link)
IF Debug THEN ; If Debug ≠ 0 then...
&LinkOpt: SETC 'DEBUG' ; ...we will gen LINK and MacsBug symbol
ELSEIF LinkAll THEN ; If LinkAll ≠ 0 then...
IF &LinkOpt ≠ 'DEBUG' THEN ; ...if user didn't specify DEBUG for &Link
&LinkOpt: SETC 'Y' ; indicate we need the LINK
ENDIF
ENDIF
IF &LinkOpt ≠ '' THEN ; Any &Link or global control setting ?
&Link#: SETA 1 ; Yes, set switch to gen LINK later
IF (&LinkOpt ≠ 'DEBUG') OR (&ModName# = '') THEN
&DbgName#: SETC '' ; If no MacsBug symbol, set global <null>
ELSE ; If MacsBug symbol, set it to gen later
&DbgName#: SETC &Concat(&UC(&ModName#), ' ')
ENDIF
ENDIF
.*
.* That's all for now -- we have no local declarations at this point...yet!
.*
&HaveDcls#: SETA 0
.*
ENDM
TITLE 'DRVRBegin - Driver primary entry point'
MACRO
DRVRBegin &Prelude,&Save==,&With==
PRINT Push,NoMDir,NoMCall
GBLC &FInfo# ; function <result>
GBLC &StFrame# ; name of current stack frame
GBLC &SaveRegs# ; Regs saved and to be restored
GBLA &NbrOfArgs# ; number of args in argument list
GBLA &Link# ; 1 ==> generate LINK
GBLA &HaveDcls# ; 1 ==> have local variables
GBLA &ArgSize# ; nbr of bytes of stack space for formals
.*
.* If we don't already think we need a LINK, we still may need it if, at this
.* point, we have to save registers and we are in a function or there are formal
.* parameters.
.*
IF &Link# OR (((&FInfo#≠'') OR (&NbrOfArgs# ≠ 0)) AND (&Save≠'')) THEN
&Link#: SETA 1 ; Link is required
IF NOT &HaveDcls# THEN ; Gen field for LINK address if no locals
LinkA6 DS.L 1
ENDIF
ENDIF
.*
.* If there we no locals, we haven't generated the FramePtr yet. So we do it now.
.*
IF NOT &HaveDcls# THEN
FramePtr EQU *
ENDIF
.*
.* That's all for the stack frame. We generate LocalSize to be used in potential
.* LINK instruction.
.*
LocalSize DS.W 0
ENDR
.*
.* Generate a WITH to cover the local stack frame and any additional templates
.* the user specified in the &With parameter. This may be a sublist or a single
.* name.
.*
IF &With ≠ '' THEN
IF &With[1:1] = '(' THEN
WITH &With[2:&Len(&With)-2],&StFrame#
ELSE
WITH &With,&StFrame#
ENDIF
ELSE
WITH &StFrame#
ENDIF
.*
.* It's time for the LINK. It is generated if &Link is 1. &Link became 1 under
.* the following conditions:
.* 1. Either the globals LinkAll or Debug are set non-zero.
.* 2. The &Link Procedure parameter is set to DEBUG or non-null
.* 3. There are local variables (Var's)
.* 4. There are registers to save (&Save), and
.* • we are processing a function, or
.* • there are formal (and, of course, actual) parameters
.* Given all this, the user can still suppress the LINK by setting &Prelude to
.* non-null.
.*
IF &Link# THEN
IF &Prelude = '' THEN
LINK A6,#LocalSize
ENDIF
FP SET A6
ELSE
FP SET A7
ENDIF
.*
.* Compute the size of the argument list to be able to pop the stack with Return.
.* Also, save registers if required.
.*
&ArgSize#: SETA &Eval(&StFrame#)-RetAddr-4
&SaveRegs#: SETC &Save
.*
PRINT Pop
ENDM
TITLE 'DRVREnter - Driver routine entry point'
MACRO
&Lbl DRVREnter &Prelude,&With==
GBLC &SaveRegs# ; Regs saved and to be restored
GBLA &Link# ; 1 ==> generate LINK
&Lbl ;
.*
.* Generate a WITH to cover any additional templates the user specified in the
.* &With parameter. This may be a sublist or a single name.
.*
IF &With ≠ '' THEN
IF &With[1:1] = '(' THEN
WITH &With[2:&Len(&With)-2]
ELSE
WITH &With
ENDIF
ENDIF
.*
.* It's time for another LINK. It is generated if &Link is 1. &Link became 1
.* under the following conditions:
.* 1. Either the globals LinkAll or Debug are set non-zero.
.* 2. The &Link Procedure parameter is set to DEBUG or non-null
.* 3. There are local variables (Var's)
.* 4. There are registers to save (&Save), and
.* • we are processing a function, or
.* • there are formal (and, of course, actual) parameters
.* Given all this, the user can still suppress the LINK by setting &Prelude to
.* non-null.
.*
IF &Link# THEN
IF &Prelude = '' THEN
LINK A6,#LocalSize
ENDIF
ENDIF
.*
.* Save registers if required.
.*
IF &SaveRegs# ≠ '' THEN
IF &Substr(&Type(&SaveRegs#), 1, 3) = 'REG' THEN
MOVE.L &SaveRegs#,-(A7)
ELSE
MOVEM.L &SaveRegs#,-(A7)
ENDIF
ENDIF
ENDM
TITLE 'DRVRExit - Driver exit'
MACRO
DRVRExit &Trap,&Force==N
.*
GBLC &SaveRegs# ; Regs saved and to be restored
GBLC &DbgName# ; name to generate for MacsBug
GBLA &Link# ; 1 ==> generate LINK
LCLC &S
.*
.* Gen code to restore any save registers
.*
IF &SaveRegs# ≠ '' THEN
IF &Substr(&Type(&SaveRegs#), 1, 3) = 'REG' THEN
MOVE.L (A7)+,&SaveRegs#
ELSE
MOVEM.L (A7)+,&SaveRegs#
ENDIF
ENDIF
.*
.* If we generated the LINK, it's time for the UNLK
.*
IF &Link# THEN
UNLK A6
ENDIF
MOVE.W &Trap,D1
BTST #noQueueBit,D1
BNE.S %L%&SysNdx
MOVE.L JIODone,-(SP)
%L%&SysNdx:
RTS
.*
.* If we need to generate the MacsBug symbol, now is the time! Be careful to
.* make sure of the Assembler's STRING setting, since the MacsBug symbol must
.* be an ASIS string.
.*
IF &DbgName# ≠ '' THEN ; &DbgName# indicates we have a symbol
&S: SETC &Setting('STRING') ; Preserve STRING status
IF &S ≠ 'ASIS' THEN ; Only change it if not already ASIS
STRING ASIS
DC.B '&DbgName#[1:8]'
STRING &S
ELSE
DC.B '&DbgName#[1:8]'
ENDIF
ENDIF
.*
ENDM
TITLE 'GNEExit - GNE filter exit'
MACRO
GNEExit &GNENext
.*
GBLC &SaveRegs# ; Regs saved and to be restored
GBLC &DbgName# ; name to generate for MacsBug
GBLA &Link# ; 1 ==> generate LINK
LCLC &S
.*
.* Gen code to restore any save registers
.*
IF &SaveRegs# ≠ '' THEN
IF &Substr(&Type(&SaveRegs#), 1, 3) = 'REG' THEN
MOVE.L (A7)+,&SaveRegs#
ELSE
MOVEM.L (A7)+,&SaveRegs#
ENDIF
ENDIF
.*
.* If we generated the LINK, it's time for the UNLK
.*
IF &Link# THEN
UNLK A6
ENDIF
MOVE.L &GNENext,-(SP)
RTS
.*
.* If we need to generate the MacsBug symbol, now is the time! Be careful to
.* make sure of the Assembler's STRING setting, since the MacsBug symbol must
.* be an ASIS string.
.*
IF &DbgName# ≠ '' THEN ; &DbgName# indicates we have a symbol
&S: SETC &Setting('STRING') ; Preserve STRING status
IF &S ≠ 'ASIS' THEN ; Only change it if not already ASIS
STRING ASIS
DC.B '&DbgName#[1:8]'
STRING &S
ELSE
DC.B '&DbgName#[1:8]'
ENDIF
ENDIF
.*
ENDM
TITLE 'Dump file "DRVRStruct.d"'
********************************************************************************
DUMP 'HD 40:MPW:AIncludes:DRVRStruct.d'
********************************************************************************
END